// SPDX-FileCopyrightText: Adam Evyčędo
//
// SPDX-License-Identifier: AGPL-3.0-or-later

package gtfs_rt

import (
	pb "apiote.xyz/p/szczanieckiej/gtfs_rt/transit_realtime"

	"archive/zip"
	"fmt"
	"io"
	"log"
	"net/http"
	"os"
	"strings"
	"time"

	"google.golang.org/protobuf/proto"
)

func GetMessages(feedID string, updatesLocation string) (*pb.FeedMessage, error) {
	var (
		message   *pb.FeedMessage
		feedURL   string
		unarchive string
		fileName  string
		bytes     []byte
	)
	if strings.Contains(updatesLocation, " | ") {
		urlCommand := strings.Split(updatesLocation, " | ")
		feedURL = urlCommand[0]
		command := strings.SplitN(urlCommand[1], " ", 2)
		unarchive = command[0]
		fileName = command[1]
	} else {
		feedURL = updatesLocation
	}

	client := http.Client{Timeout: 5 * time.Second}
	response, err := client.Get(feedURL)
	if err != nil {
		return nil, fmt.Errorf("while getting: %w", err)
	}

	switch unarchive {
	case "zip":
		tmp, err := os.CreateTemp("", "gtfsrt")
		if err != nil {
			return nil, fmt.Errorf("while creating temporary file for gtfs-rt: %w", err)
		}
		io.Copy(tmp, response.Body)
		z, err := zip.OpenReader(tmp.Name())
		if err != nil {
			return nil, fmt.Errorf("while opening temporary file for unzipping gtfs-rt: %w", err)
		}
		for _, file := range z.File {
			if file.Name == fileName {
				srcFile, err := file.Open()
				if err != nil {
					return nil, fmt.Errorf("while openning zipped file: %w", err)
				}
				bytes, err = io.ReadAll(srcFile)
				if err != nil {
					return nil, fmt.Errorf("while reading zipped file: %w", err)
				}
				break
			}
		}
		err = os.Remove(tmp.Name())
		if err != nil {
			log.Println("failed removing temporary zip file")
		}
	case "":
		bytes, err = io.ReadAll(response.Body)
		if err != nil {
			return nil, fmt.Errorf("while reading body: %w", err)
		}
	}

	message = new(pb.FeedMessage)
	if err := proto.Unmarshal(bytes, message); err != nil {
		return nil, fmt.Errorf("Failed to parse message: %w", err)
	}
	return message, nil
}
